<?php

namespace App\Services;

use App\Models\InvitationCode;
use Exception;
use Illuminate\Support\Facades\Auth as AuthFacades;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;
use PHPExcel_Cell;
use PHPExcel_IOFactory;
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
use Illuminate\Support\Facades\Log;

class HelperService
{

    protected $authCodeKey = '23E824B054B97CDD97D8FEF8351AC06F';
    /**
     * 导入excel拼装数据并下载照片
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-01-18
     * @param string $fileUrl
     * @param string $typeName
     * @return array
     */

    public function import_excel($file, $typeName, int $sheet = 0, int $columnCnt = 0)
    {
        try {

            $inputFileName = $file;

            $inputFileType = PHPExcel_IOFactory::identify($inputFileName);

            $objReader = PHPExcel_IOFactory::createReader($inputFileType);

            $objPHPExcel = $objReader->load($inputFileName);
        } catch (\Exception $e) {

            swoole_exit('加载文件发生错误："' . pathinfo($inputFileName, PATHINFO_BASENAME) . '": ' . $e->getMessage());
        }
        $sheet = $objPHPExcel->getSheet(0);

        $data = $sheet->toArray(); //该方法读取不到图片，图片需单独处理

        //设置图片路径
        $imageFilePath = storage_path('/app/upload/' . date('Ym/d') . '/' . $typeName . '/'); //图片保存目录

        if (!file_exists($imageFilePath)) {
            // 如果路径不存在创建
            mkdir($imageFilePath, 0777, true);
        }

        //处理图片
        foreach ($sheet->getDrawingCollection() as $img) {
            //获取图片所在行和列
            list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($img->getCoordinates());

            $imageFileName = $img->getCoordinates() . create_randomstr();

            switch ($img->getExtension()) {
                case 'jpg':
                    $imageFileName .= '.jpg';
                    $source = @imagecreatefromjpeg($img->getPath());
                    imagejpeg($source, $imageFilePath . $imageFileName);
                    break;
                case 'jpeg':
                    $imageFileName .= '.jpeg';
                    $source = @imagecreatefromjpeg($img->getPath());
                    imagejpeg($source, $imageFilePath . $imageFileName);
                    break;
                case 'gif':
                    $imageFileName .= '.gif';
                    $source = @imagecreatefromgif($img->getPath());
                    imagejpeg($source, $imageFilePath . $imageFileName);
                    break;
                case 'png':
                    $imageFileName .= '.png';
                    $source = @imagecreatefrompng($img->getPath());
                    imagejpeg($source, $imageFilePath . $imageFileName);
                    break;
            }
            $startColumn = $this->ABC2decimal($startColumn); //由于图片所在位置的列号为字母，转化为数字
            $data[$startRow - 1][$startColumn] = $imageFilePath . $imageFileName; //把图片插入到数组中

        }

        return $data;
    }

    /**
     * 生成随机字符串
     * @param string $lenth 长度
     * @return string 字符串
     */
    public function create_randomstr($lenth = 6)
    {

        return Str::random($lenth);
    }

    public function ABC2decimal($abc)
    {
        $ten = 0;
        $len = strlen($abc);
        for ($i = 1; $i <= $len; $i++) {
            $char = substr($abc, 0 - $i, 1); //反向获取单个字符

            $int = ord($char);
            $ten += ($int - 65) * pow(26, $i - 1);
        }
        return $ten;
    }


    /**
     * 下载远程文件到本地文件夹 \storage\app\public
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-08-15
     * @param string $url
     * @param [type] $savePath  文件夹分类
     * @return void
     */
    public function downloadFile($url = '', $savePath)
    {
        if (empty($url)) {
            return [];
        }

        $client = new \GuzzleHttp\Client(['verify' => false]);
        $file_name = pathinfo($url)['basename'];
        $file_temp_path = $savePath . '/' . date('Y-m-d') . '/' . $file_name; //保存文件地址+原始文件名

        $tempData = $client->request('get', $url)->getBody()->getContents();

        $judge = Storage::disk('public')->put($file_temp_path, $tempData); //storage/app/public/document/remoteFiles文件保存地址

        if ($judge) {
            return 'storage/app/public/' . $file_temp_path;
        }
    }

    /**
     * 七牛云上传文件
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-01-18
     * @param string $url
     * @return string
     */
    public function qiniuUplode($url, $fileName, $ext)
    {

        $config = config('filesystems.disks.qiniu');

        $accessKey = $config['access_key']; //七牛云密钥管理
        $secretKey = $config['secret_key']; //七牛云密钥管理

        $bucket = $config['bucket'];
        $uploadMgr = new UploadManager();
        $auth = new Auth($accessKey, $secretKey);
        $token = $auth->uploadToken($bucket);
        Log::notice('qiniuUplode：' . json_encode($url));
        // dd($url);
        //选择单个图片 图片放在public下
        list($ret, $error) = $uploadMgr->putFile($token, $fileName, $url);
        //  list($ret, $error) = $uploadMgr->putFile($token, $fileName, $url, null, 'application/octet-stream', false, 'progress.log', 'v2');
        Log::notice('$ret：' . json_encode($ret));
        Log::notice('$error：' . json_encode($error));
        if ($error !== null) {
            throw new Exception('上传出错' . serialize($error));
        }
        Log::notice('domains：' . $config['domains']['https'] . $ret['key']);
        return $config['domains']['https'] . $ret['key'];
    }

    /**
     * 获取七牛云资源列表
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-02-15
     * @param int $page
     * @return json
     */
    public function getQiniuList($marker = '')
    {

        $config = config('filesystems.disks.qiniu');

        $accessKey = $config['access_key']; //七牛云密钥管理

        $secretKey = $config['secret_key']; //七牛云密钥管理

        $bucket = $config['bucket'];

        $auth = new Auth($accessKey, $secretKey);

        $bucketManager = new BucketManager($auth);

        $token = $auth->uploadToken($bucket);
        // if(is_string($marker)){
        //     $params = explode('-',$marker);
        //     $marker = $params[0];
        //     $page = $params[1];
        // }else{

        //     $page = $marker;
        //     dump('page'.$page);
        // }

        // 要列取文件的公共前缀
        $prefix = '';
        // dump($marker);
        // 上次列举返回的位置标记，作为本次列举的起点信息。
        // if(is_numeric($marker)){
        //     $marker = '';
        // }

        // dump($marker);die;
        // 本次列举的条目数
        $limit = 20;

        $delimiter = '/';
        // 列举文件
        list($ret, $err) = $bucketManager->listFiles($bucket, $prefix, $marker, $limit, $delimiter);
        if ($err !== null) {
            echo "\n====> list file err: \n";
            var_dump($err);
        } else {
            if (array_key_exists('marker', $ret)) {
                // Cache::put('marker'.$page,$ret['marker']);
                // echo "HelperMarker:  " . $ret["marker"] . "\n";
            }

            return $ret;
        }
    }

    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\Guard
     */
    public function guard()
    {
        return AuthFacades::guard('api');
    }

    public function member()
    {
        $userid = AuthFacades::guard('api')->payload()->get('sub');
        $user = $this->guard()->user();
        $user->load(['doctor' => function ($query) {
            $query->select('id', 'user_id', 'real_name', 'status', 'status as status_text', 'reason');
        }]);
        return $user;
    }

    /**
     * 对信息库数据进行二次拼装
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-03-09
     * @param array $info
     * @param array $follow
     * @param array $chooes
     * @return mixed
     */
    public function infoArray($info = [], $follow_id = [], $chooes_id = [])
    {
        if (empty($info) && empty($follow_id)) {
            return [];
        }

        foreach ($info as $key => $val) {

            if (in_array($val['id'], $follow_id)) {

                $info[$key]['is_follow'] = 1;
            } else {
                $info[$key]['is_follow'] = 0;
            }
        }

        // if($chooes_id){
        foreach ($info as $key => $val) {
            if (in_array($val['id'], $chooes_id)) {

                $info[$key]['is_chooes'] = 1;
            } else {

                $info[$key]['is_chooes'] = 0;
            }
        }
        // }

        return $info;
    }

    /**
     * 导出excel表
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-03-31
     * @param array $header
     * @param string $title
     * @param array $list
     * @param array $width
     * @return void
     */
    public function exportExcel($header, $title, $list, $width)
    {
        array_unshift($list, $header);
        Excel::create(iconv('UTF-8', 'GBK', $title), function ($excel) use ($list, $width) {
            $excel->sheet('score', function ($sheet) use ($list, $width) {
                $sheet->rows($list);
                $sheet->setWidth($width);
            });
        })->export('xls');
    }

    /**
     * 获取用户id
     *
     * @Author hechengwei
     * @email chichiooo@sina.com
     * @DateTime 2022-04-14
     * @return void
     */
    public function memberId()
    {
        // $userid = AuthFacades::guard('api')->payload()->get('sub');
        // if (Redis::exists('user:' . $userid)) {
        //     $user = Redis::hGetAll('user:' . $userid);
        //     return (int) $user['userid'];
        // } else {
        return $this->guard()->id();
        // }
    }

    //递归方式把数组或字符串 null转换为空''字符串
    public static function _unsetNull($arr)
    {

        if ($arr !== null) {
            if (is_array($arr)) {
                if (!empty($arr)) {
                    foreach ($arr as $key => $value) {
                        if ($value === null) {
                            $arr[$key] = '';
                        } else {
                            $arr[$key] = self::_unsetNull($value); //递归再去执行
                        }
                    }
                }
            } else {
                if ($arr === null) {
                    $arr = '';
                } //注意三个等号
            }
        } else {
            $arr = '';
        }

        return $arr;
    }

    /**
     * 把返回的数据集转换成Tree
     * @access public
     * @param array $list 要转换的数据集
     * @param string $pid parent标记字段
     * @param string $level level标记字段
     * @return array
     */
    function list_to_tree(array $array, string $first, string $pid, string $id, string $child = 'childs'): array
    {
        $items = array();
        foreach ($array as $value) {
            $items[$value[$id]] = $value;
        }
        //第二部 遍历数据 生成树状结构
        $tree = array();
        foreach ($items as $key => $value) {
            if (isset($items[$value[$pid]])) {
                $items[$value[$pid]][$child][] = &$items[$key];
            } else {
                $tree[] = &$items[$key];
            }
        }
        return $tree;
    }

    /**
     * 对查询结果集进行排序
     * @access public
     * @param array $list 查询结果
     * @param string $field 排序的字段名
     * @param array $sortby 排序类型
     * asc正向排序 desc逆向排序 nat自然排序
     * @return array
     */
    public function list_sort_by($list, $field, $sortby = 'asc')
    {
        if (is_array($list)) {
            $refer = $resultSet = array();
            foreach ($list as $i => $data)
                $refer[$i] = &$data[$field];
            switch ($sortby) {
                case 'asc': // 正向排序
                    asort($refer);
                    break;
                case 'desc': // 逆向排序
                    arsort($refer);
                    break;
                case 'nat': // 自然排序
                    natcasesort($refer);
                    break;
            }
            foreach ($refer as $key => $val)
                $resultSet[] = &$list[$key];
            return $resultSet;
        }
        return false;
    }


    /**
     * 在数据列表中搜索
     * @access public
     * @param array $list 数据列表
     * @param mixed $condition 查询条件
     * 支持 array('name'=>$value) 或者 name=$value
     * @return array
     */
    public function list_search($list, $condition)
    {
        if (is_string($condition))
            parse_str($condition, $condition);
        $resultSet = array();
        foreach ($list as $key => $data) {
            $find = false;
            foreach ($condition as $field => $value) {
                if (isset($data[$field])) {
                    if (0 === strpos($value, '/')) {
                        $find = preg_match($value, $data[$field]);
                    } elseif ($data[$field] == $value) {
                        $find = true;
                    }
                }
            }
            if ($find)
                $resultSet[] = &$list[$key];
        }
        return $resultSet;
    }

    /**
     * @param $arr
     * @param $key_name
     * @return array
     * 将数据库中查出的列表以指定的 id 作为数组的键名
     */
    public function convert_arr_key($arr, $key_name)
    {
        $arr2 = array();
        foreach ($arr as $key => $val) {
            $arr2[$val[$key_name]] = $val;
        }
        return $arr2;
    }


    /**
     * @param $arr
     * @param $key_name
     * @param $key_name2
     * @return array
     * 将数据库中查出的列表以指定的 id 作为数组的键名 数组指定列为元素 的一个数组
     */
    public function get_id_val($arr, $key_name, $key_name2)
    {
        $arr2 = array();
        foreach ($arr as $key => $val) {
            $arr2[$val[$key_name]] = $val[$key_name2];
        }
        return $arr2;
    }


    // PHP快速高效的将多维数组降维
    function flareout_array($array)
    {

        $return = [];

        array_walk_recursive($array, function ($x) use (&$return) {

            $return[] = $x;
        });
        return $return;
    }

    /**
     * @ 0-存数字字符串；1-小写字母字符串；2-大写字母字符串；3-大小写数字字符串；4-字符；
     *   5-数字，小写，大写，字符混合
     * @param  integer $type   [字符串的类型]
     * @param  integer $length [字符串的长度]
     * @param  integer $time   [是否带时间1-带，0-不带]
     * @return [string]  $str    [返回唯一字符串]
     */
    function randCode($len)
    {
        while (true) {
            $res = substr(base_convert(md5(uniqid(md5(microtime(true)), true)), 16, 10), 0, $len);
            $code = InvitationCode::where('code', $res)->first();
            if (!$code) {
                break;
            }
        }

        return $res;
    }

    function useInvitationCode($code, $userId)
    {
        $where = [
            'code' => $code,
            'type' => 'medical',
            'status' => 0,
        ];
        $data = InvitationCode::where($where)->first();
        if (empty($data)) return '';
        $data->use_time = date('Y-m-d H:i:s', time());
        $data->status = 1;
        $data->save();
        return $data->toArray();
    }
}
